/*
 * VHClubSummaryGrid.java
 * Created on 20 sept. 2009
 *
 * VirtualHockey Internet Platform
 * http://code.google.com/p/virtualhockey/
 *
 * Copyright (c) 2005-2009, Jens and Jan Janke (VirtualHockey Project)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */

package com.hockeo.vhweb.client.ui.widget;

import java.util.ArrayList;
import java.util.Map;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.GridGroupRenderer;
import com.extjs.gxt.ui.client.widget.grid.GroupColumnData;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.hockeo.vhweb.client.VHMain;
import com.hockeo.vhweb.client.mvc.VHController;
import com.hockeo.vhweb.client.res.VHResConstants;
import com.hockeo.vhweb.client.res.VHResMessages;
import com.hockeo.vhweb.client.rpc.VHRpcCallback;
import com.hockeo.vhweb.client.rpc.VHRpcResultReceiver;
import com.hockeo.vhweb.client.utils.VHJsData;
import com.hockeo.vhweb.client.utils.VHJsSimpleData;

/**
 * Grid that displays an overview of the most important club specific statistics.
 *
 * @version $Id$
 * @author jjanke
 */
public class VHClubSummaryGrid extends LayoutContainer implements VHRpcResultReceiver<Map<String, VHJsData>>
{
  private static final String                  COL_VALUE    = "value";
  private static final String                  COL_LABEL    = "label";
  private static final String                  COL_ICON     = "icon";
  private static final String                  COL_ORDER    = "order";
  private static final String                  COL_CATEGORY = "category";

  private final GroupingStore<VHJsData>        d_store;
  private Grid<VHJsData>                       d_grid;
  private VHJsData                             d_club;
  private VHRpcCallback<Map<String, VHJsData>> d_callback;

  /**
   * Builds a new club summary grid.
   *
   * @param club the club for which to initially build the summary
   */
  public VHClubSummaryGrid( VHJsData club )
  {
    d_store = new GroupingStore<VHJsData>();

    setClub( club );
    buildGrid();
    setLayout( new FitLayout() );
    add( d_grid );
  }

  public void setClub( VHJsData club )
  {
    // If the club has already been set, we do not recalculate the table content
    //
    if ( d_club != null && d_club.getId().equals( club.getId() ) )
      return;

    d_club = club;

    // Remove all the data that may already be there
    //
    d_store.removeAll();
    d_store.groupBy( COL_CATEGORY );

    VHJsSimpleData data;
    VHResConstants consts = VHMain.getConstants();

    // 1st category: general club information
    //
    data = new VHJsSimpleData( "homeCountry" );
    data.set( COL_CATEGORY, consts.clubDataCategoryGeneralInfo() );
    data.set( COL_ORDER, 101 );
    data.set( COL_LABEL, consts.clubDataLabelHomeCountry() );
    data.set( COL_VALUE, d_club.get( "country_translated" ) );
    d_store.add( data );

    data = new VHJsSimpleData( "association" );
    data.set( COL_CATEGORY, consts.clubDataCategoryGeneralInfo() );
    data.set( COL_ORDER, 102 );
    data.set( COL_LABEL, consts.clubDataLabelAssociation() );
    data.set( COL_VALUE, d_club.get( "association_name" ) );
    d_store.add( data );

    data = new VHJsSimpleData( "location" );
    data.set( COL_CATEGORY, consts.clubDataCategoryGeneralInfo() );
    data.set( COL_ORDER, 103 );
    data.set( COL_LABEL, consts.clubDataLabelLocation() );
    data.set( COL_VALUE, d_club.get( "latitude" ) + " / " + d_club.get( "longitude" ) );
    d_store.add( data );

    // 2nd category: past season statistics (number of championchips, promotions etc.)
    //
    data = new VHJsSimpleData( "numLeagueTitles" );
    data.set( COL_CATEGORY, consts.clubDataCategoryKeyFigures() );
    data.set( COL_ORDER, 201 );
    data.set( COL_ICON, "images/contests/league_16.png" );
    data.set( COL_LABEL, consts.clubDataLabelNationalTitles() );
    data.set( COL_VALUE, d_club.getInt( "stats_numLeagueTitles" ) );
    d_store.add( data );

    data = new VHJsSimpleData( "numMinorLeagueTitles" );
    data.set( COL_CATEGORY, consts.clubDataCategoryKeyFigures() );
    data.set( COL_ORDER, 202 );
    data.set( COL_ICON, "images/contests/league_16.png" );
    data.set( COL_LABEL, consts.clubDataLabelMinorLeagueTitles() );
    data.set( COL_VALUE, d_club.getInt( "stats_numMinorLeagueTitles" ) );
    d_store.add( data );

    data = new VHJsSimpleData( "numCupTitles" );
    data.set( COL_CATEGORY, consts.clubDataCategoryKeyFigures() );
    data.set( COL_ORDER, 203 );
    data.set( COL_ICON, "images/contests/cup_16.png" );
    data.set( COL_LABEL, consts.clubDataLabelCupTitles() );
    data.set( COL_VALUE, d_club.getInt( "stats_numCupTitles" ) );
    d_store.add( data );

    data = new VHJsSimpleData( "numEU1Titles" );
    data.set( COL_CATEGORY, consts.clubDataCategoryKeyFigures() );
    data.set( COL_ORDER, 204 );
    data.set( COL_ICON, "images/contests/cl_16.png" );
    data.set( COL_LABEL, consts.clubDataLabelEU1Titles() );
    data.set( COL_VALUE, d_club.getInt( "stats_numEU1Titles" ) );
    d_store.add( data );

    data = new VHJsSimpleData( "numEU2Titles" );
    data.set( COL_CATEGORY, consts.clubDataCategoryKeyFigures() );
    data.set( COL_ORDER, 205 );
    data.set( COL_ICON, "images/contests/wl_16.png" );
    data.set( COL_LABEL, consts.clubDataLabelEU2Titles() );
    data.set( COL_VALUE, d_club.getInt( "stats_numEU2Titles" ) );
    d_store.add( data );

    data = new VHJsSimpleData( "numPromotions" );
    data.set( COL_CATEGORY, consts.clubDataCategoryKeyFigures() );
    data.set( COL_ORDER, 206 );
    data.set( COL_ICON, "images/picto/rank_promoted.gif" );
    data.set( COL_LABEL, consts.clubDataLabelPromotions() );
    data.set( COL_VALUE, d_club.getInt( "stats_numPromotions" ) );
    d_store.add( data );

    data = new VHJsSimpleData( "numRelegations" );
    data.set( COL_CATEGORY, consts.clubDataCategoryKeyFigures() );
    data.set( COL_ORDER, 207 );
    data.set( COL_ICON, "images/picto/rank_relegated.gif" );
    data.set( COL_LABEL, consts.clubDataLabelRelegations() );
    data.set( COL_VALUE, d_club.getInt( "stats_numRelegations" ) );
    d_store.add( data );

    // 3rd category: current situation (league, cup, cl, wl, ecr, etc.). Will be set using
    // data acquired via RPC.
    //
    if ( d_callback == null )
      d_callback = new VHRpcCallback<Map<String, VHJsData>>( this, null );

    VHController.getBaseDataService().getCurrentClubSituation( VHController.getLocale(), d_club.getId(), d_callback );
  }

  public void setRpcData( Map<String, VHJsData> mapResult, String strPurpose )
  {
    VHJsData src;
    VHJsSimpleData data;
    VHResConstants consts = VHMain.getConstants();
    VHResMessages msg = VHMain.getMessages();

    // league
    //
    src = mapResult.get( "league" );
    data = new VHJsSimpleData( "situationLeague" );
    data.set( COL_CATEGORY, consts.clubDataCategoryCurrentSituation() );
    data.set( COL_ORDER, 301 );
    data.set( COL_ICON, "images/contests/league_16.png" );
    data.set( COL_LABEL, msg.clubDataLabelLeagueSituation( d_club.getString( "league_id_translated" ),
        d_club.getInt( "league_category" ) ) );
    data.set( COL_VALUE, msg.clubDataValueLeagueStandings( src.getInt( "rank" ),
        src.getString( "rankType_translated" ), src.getInt( "numPoints" ), src.getInt( "numMatches" ),
        src.getInt( "numTotalMatches" ), src.getInt( "matchday_num" ), src.getInt( "numTotalMatchdays" ), src.getDouble( "remainingGoals" ) ) );
    d_store.add( data );

    // cup
    //
    src = mapResult.get( "cup" );
    data = new VHJsSimpleData( "situationCup" );
    data.set( COL_CATEGORY, consts.clubDataCategoryCurrentSituation() );
    data.set( COL_ORDER, 302 );
    data.set( COL_ICON, "images/contests/cup_16.png" );
    data.set( COL_LABEL, msg.clubDataLabelCupSituation( d_club.getString( "association_nationalCupId_translated" ) ) );

    if ( src != null )
    {
      String strStatus = src.getString( "multiRoundContestStatus" );

      if ( strStatus.equals( "ELIMINATED" ) )
        data.set( COL_VALUE, msg.clubDataValueEliminated( src.getString( "reachedRound_translated" ) ) );
      else if ( strStatus.equals( "QUALIFIED" ) )
        data.set( COL_VALUE, msg.clubDataValueQualified( src.getString( "reachedRound_translated" ) ) );
      else if ( strStatus.equals( "REACHED_LAST_ROUND" ) )
        data.set( COL_VALUE, consts.clubDataValueLostFinal() );
      else
        data.set( COL_VALUE, src.getString( "reachedRound_translated" ) );
    }
    else
      data.set( COL_VALUE, consts.clubDataValueNotParticipating() );

    d_store.add( data );

    // Champions League
    //
    src = mapResult.get( "cl" );
    data = new VHJsSimpleData( "situationCL" );
    data.set( COL_CATEGORY, consts.clubDataCategoryCurrentSituation() );
    data.set( COL_ORDER, 303 );
    data.set( COL_ICON, "images/contests/cl_16.png" );
    data.set( COL_LABEL, consts.championsLeague() );

    if ( src != null )
    {
      String strStatus = src.getString( "multiRoundContestStatus" );

      if ( strStatus.equals( "ELIMINATED" ) )
        data.set( COL_VALUE, msg.clubDataValueEliminated( src.getString( "reachedRound_translated" ) ) );
      else if ( strStatus.equals( "QUALIFIED" ) )
        data.set( COL_VALUE, msg.clubDataValueQualified( src.getString( "reachedRound_translated" ) ) );
      else if ( strStatus.equals( "REACHED_LAST_ROUND" ) )
        data.set( COL_VALUE, consts.clubDataValueLostFinal() );
      else
        data.set( COL_VALUE, src.getString( "reachedRound_translated" ) );
    }
    else
      data.set( COL_VALUE, consts.clubDataValueNotParticipating() );

    d_store.add( data );

    // World League
    //
    src = mapResult.get( "wl" );
    data = new VHJsSimpleData( "situationWL" );
    data.set( COL_CATEGORY, consts.clubDataCategoryCurrentSituation() );
    data.set( COL_ORDER, 304 );
    data.set( COL_ICON, "images/contests/wl_16.png" );
    data.set( COL_LABEL, consts.worldLeague() );

    if ( src != null )
    {
      String strStatus = src.getString( "multiRoundContestStatus" );

      if ( strStatus.equals( "ELIMINATED" ) )
        data.set( COL_VALUE, msg.clubDataValueEliminated( src.getString( "reachedRound_translated" ) ) );
      else if ( strStatus.equals( "QUALIFIED" ) )
        data.set( COL_VALUE, msg.clubDataValueQualified( src.getString( "reachedRound_translated" ) ) );
      else if ( strStatus.equals( "REACHED_LAST_ROUND" ) )
        data.set( COL_VALUE, consts.clubDataValueLostFinal() );
      else
        data.set( COL_VALUE, src.getString( "reachedRound_translated" ) );
    }
    else
      data.set( COL_VALUE, consts.clubDataValueNotParticipating() );

    d_store.add( data );

    // ECR
    //
    src = mapResult.get( "ecr" );
    data = new VHJsSimpleData( "situationECR" );
    data.set( COL_CATEGORY, consts.clubDataCategoryCurrentSituation() );
    data.set( COL_ORDER, 305 );
    data.set( COL_ICON, "images/nav/standings.png" );
    data.set( COL_LABEL, consts.navMainECR() );
    data.set( COL_VALUE, src != null ? msg.clubDataValueECR( src.getInt( "rank" ), src.getDouble( "pointsTotal" ), src.getString( "season_name" ) ) : consts.noDataAvailable() );
    d_store.add( data );

    d_store.sort( COL_ORDER, SortDir.ASC );
  }

  private void buildGrid()
  {
    // Cell rendering
    //
    GridCellRenderer<VHJsData> renderer = new GridCellRenderer<VHJsData>() {
      public String render( VHJsData kom, String strProperty, ColumnData config, int rowIndex, int colIndex,
          ListStore<VHJsData> store, Grid<VHJsData> grid )
      {
        if ( strProperty.equals( COL_ICON ) )
          if ( kom.getString( strProperty ) != null )
            return "<img src='" + kom.getString( strProperty ) + "'/>";
          else
            return null;
        else if ( strProperty.equals( COL_ORDER ) )
          return "";

        return String.valueOf( kom.get( strProperty ) );
      }
    };

    // Column definitions
    //
    ArrayList<ColumnConfig> listCols = new ArrayList<ColumnConfig>();
    ColumnConfig col;

    col = new ColumnConfig();
    col.setId( COL_CATEGORY );
    col.setWidth( 0 );
    col.setAlignment( HorizontalAlignment.LEFT );
    col.setResizable( false );
    col.setHidden( true );
    col.setMenuDisabled( true );
    col.setSortable( false );
    listCols.add( col );

    // Although this column should be invisible, it is marked as visible because when
    // sorting by this column and it is invisible, an assertion error appears (GXT bug?).
    //
    col = new ColumnConfig();
    col.setId( COL_ORDER );
    col.setWidth( 0 );
    col.setAlignment( HorizontalAlignment.LEFT );
    col.setResizable( false );
    col.setHidden( false );
    col.setMenuDisabled( true );
    col.setSortable( false );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( COL_ICON );
    col.setWidth( 26 );
    col.setAlignment( HorizontalAlignment.CENTER );
    col.setResizable( false );
    col.setHidden( false );
    col.setMenuDisabled( true );
    col.setSortable( false );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( COL_LABEL );
    col.setWidth( 150 );
    col.setAlignment( HorizontalAlignment.LEFT );
    col.setResizable( true );
    col.setHidden( false );
    col.setMenuDisabled( true );
    col.setSortable( false );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( COL_VALUE );
    col.setWidth( 300 );
    col.setAlignment( HorizontalAlignment.LEFT );
    col.setResizable( true );
    col.setHidden( false );
    col.setMenuDisabled( true );
    col.setSortable( false );
    listCols.add( col );

    final ColumnModel cm = new ColumnModel( listCols );

    GroupingView view = new GroupingView();

    view.setForceFit( true );
    view.setGroupRenderer( new GridGroupRenderer() {
      public String render( GroupColumnData data )
      {
        VHJsData dataFirst = (VHJsData) data.models.get( 0 );

        return dataFirst.getString( COL_CATEGORY );
      }
    } );

    // Grid
    //
    d_grid = new Grid<VHJsData>( d_store, cm );
    d_grid.setView( view );
    d_grid.setAutoExpandColumn( COL_VALUE );
    d_grid.setHideHeaders( true );
    d_grid.setStripeRows( false );
    d_grid.setBorders( true );
    d_grid.setAutoWidth( true );
  }
}
